package com.yanqu.road.server.gameplayer.module.activity.carptrip;

import com.yanqu.road.dao.impl.activity.carptrip.CarpTripPvPReportDataDaoImpl;
import com.yanqu.road.dao.impl.activity.carptrip.UserCarpTripDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.args.ValueParamArgs;
import com.yanqu.road.entity.activity.carptrip.CarpTripConfig;
import com.yanqu.road.entity.activity.carptrip.UserCarpTripEvent;
import com.yanqu.road.entity.activity.carptrip.config.*;
import com.yanqu.road.entity.activity.carptrip.data.CarpTripPvPReportData;
import com.yanqu.road.entity.activity.carptrip.data.UserCarpTripData;
import com.yanqu.road.entity.activity.carptrip.enums.eCarpTripCellType;
import com.yanqu.road.entity.activity.carptrip.enums.eCarpTripEventType;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.*;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.CarpTripProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.carptrip.CarpTripMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.pb.CarpTripActivityPb;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class CarpTripModule extends GeneralModule {

    UserCarpTripData userData;

    private List<CarpTripPvPReportData> reportDataList;

    public CarpTripModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = CarpTripMgr.getActivityInfo();
        if (ActivityMgr.activityInShowTime(activityInfo)) {
            userData = new UserCarpTripDataDaoImpl().getUserCarpTripData(activityInfo.getActivityId(), player.getUserId());
            reportDataList = new CarpTripPvPReportDataDaoImpl().getCarpTripPvPReportData(activityInfo.getActivityId(), player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        if(userData != null && reportDataList != null){
            if(reportDataList.size() > 0){
                CarpTripPvPReportData reportData = reportDataList.get(0);
                if(userData.getLastReadTime() < reportData.getTime() && userData.getTopCellNum() == reportData.getOldCellNum()){
                    userData.setTopCellNum(reportData.getNewCellNum());
                    CarpTripMgr.getLogger().info("-------跃龙门----- player {} drop to {}", player.getUserId(), userData.getTopCellNum());
                }
            }
        }
        return true;
    }

    @Override
    public boolean saveData() {
        if(userData != null) {
            if (userData.isInsertOption()) {
                new UserCarpTripDataDaoImpl().add(userData);
            }else if (userData.isUpdateOption()){
                new UserCarpTripDataDaoImpl().update(userData);
            }
        }
        if(reportDataList != null){
            for (int i = 0; i < reportDataList.size(); i++) {
                CarpTripPvPReportData data = reportDataList.get(i);
                if(data.isInsertOption()){
                    new CarpTripPvPReportDataDaoImpl().add(data);
                }
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.CarpTripActivity.getValue())) {
            return;
        }

        syncConfig();

        syncUserData();

        syncPveData();
    }

    public void syncConfig() {

        CarpTripConfig config = CarpTripMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        CarpTripProto.CarpTripConfigSyncMsg.Builder configSync = CarpTripProto.CarpTripConfigSyncMsg.newBuilder();

        int userPassId = 0;
        if(userData != null){
            userPassId = userData.getEvent().getPassId();
        }
        buildPassCellTempList(config, configSync, userPassId, userData);

        configSync.addAllBossReward(CarpTripMgr.getBossRewardTempList());

        CarpTripActivityPb.buildOtherConfig(config, configSync);

        player.sendPacket(Protocol.U_CARP_TRIP_SYNC_CONFIG, configSync);
    }

    public void buildPassCellTempList(CarpTripConfig config, CarpTripProto.CarpTripConfigSyncMsg.Builder configSync, int userPassId, UserCarpTripData userData) {
        //最多下发两个boss之间的数据,外加最多6层
        int showBossNum = 1;
        int showTopSix = 6;
        //boss后面强制加一层
        int add = 1;
        List<Integer> handledCellList = new ArrayList<>();
        if(userData != null){
            handledCellList = userData.getPreHandleList();
        }
        for (CarpTripLevelInfo levelInfo : config.getLevelInfoList()) {
            if(showBossNum <= 0 && configSync.getPassCount() >= showTopSix && add == 0){
                break;
            }
            if(levelInfo.getId() < userPassId - 1 && add == 0){
                continue;
            }
            for (CarpTripProto.CarpTripPassCellTemp.Builder builder : CarpTripActivityPb.buildLevelConfig(levelInfo, config, handledCellList)) {
                if(add <= 0){
                    break;
                }
                configSync.addPass(builder);
                if(showBossNum <= 0){
                    add--;
                }
            }
            //展示到下一个boss阶段终止
            if(levelInfo.getId() > userPassId && levelInfo.getBossId() > 0){
                showBossNum--;
            }
        }
    }

    /**
     * 同步玩家数据
     */
    public void syncUserData() {

        CarpTripConfig config = CarpTripMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        if(SystemOpenMgr.systemOpen(player, eSystemId.CarpTripActivity.getValue())){
            if(userData == null || userData.getActivityId() != CarpTripMgr.getActivityId()){
                initUserData();
            }
        }

        if(userData == null){
            return;
        }
        recoverUserEnergyPower();

        CarpTripRoleInfo roleInfo = config.getCarpTripRoleInfo(userData.getExp());

        CarpTripProto.CarpTripDataSyncMsg.Builder syncMsg = CarpTripProto.CarpTripDataSyncMsg.newBuilder();
        CarpTripProto.CarpTripUserDataTemp.Builder builder = CarpTripActivityPb.buildUserData(userData, roleInfo);
        syncMsg.setUserData(builder);
        player.sendPacket(Protocol.U_CARP_TRIP_SYNC_DATA, syncMsg);
    }

    //同步pvp数据
    public void syncPveData(){
        if(userData == null){
            return;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        if(userData.getCellNum() < config.getTotalCellNum()){
            return;
        }

        if(userData.getTopCellNum() <= 0){
            return;
        }

        //上跨服去pvp关卡数据
        player.sendPacket(Protocol.C_CARP_TRIP_SYNC_PVP_TOP, CarpTripProto.CrossGetCarpTripPVPCellDataReqMsg.newBuilder().setActivityId(userData.getActivityId())
                .setAbility(userData.getAbility().toString()));
    }

    /**
     * 初始化玩家数据
     */
    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.CarpTripActivity.getValue())) {
            return;
        }

        // 没有活动
        if (!ActivityMgr.activityInShowTime(CarpTripMgr.getActivityInfo()) || CarpTripMgr.getConfig() == null) {
            return;
        }

        ActivityInfo activityInfo = CarpTripMgr.getActivityInfo();

        // 已经有数据了
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();

        UserCarpTripData tmpUserData = new UserCarpTripData();
        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setLastRecoverPowerTime(System.currentTimeMillis());
        tmpUserData.setPower(config.getAuraMax());
        tmpUserData.setAbility(BigInteger.valueOf(config.getPlayerStrengthBegin()));
        tmpUserData.setDrawUpLv(1);
        tmpUserData.setInsertOption();

        userData = tmpUserData;

    }

    /**
     * 体力恢复
     */
    public void recoverUserEnergyPower() {
        if (userData == null || CarpTripMgr.getConfig() == null) {
            return;
        }
        int beforeVal = userData.getPower();
        CarpTripConfig config = CarpTripMgr.getConfig();
        CalcPowerResult calcPowerResult = PowerHelper.calcPower(userData.getLastRecoverPowerTime() / 1000,
                config.getAuraGetCd() , config.getAuraGetNum(), config.getAuraMax(), userData.getPower());

        userData.setPower(calcPowerResult.getCurPower());
        userData.setLastRecoverPowerTime(calcPowerResult.getLastRecoverTime() * 1000);

        if(beforeVal != userData.getPower()){
            AutoLogMgr.add(new LogCarpTripPower(userData.getActivityId(), player.getUserId(), 2, beforeVal, userData.getPower() - beforeVal, userData.getPower()));
        }
    }

    /**
     * 爬塔
     * @param x 下一层通道（起始0）
     */
    public int climbTower(int x) {

        if (player.isRequestToFast()) {
            return GameErrorCode.E_REQUEST_TOO_FAST;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        if(userData == null){
            return GameErrorCode.E_CARP_TRIP_LOCK;
        }

        synchronized (userData) {
            CarpTripCell cell = CarpTripMgr.getCell(userData.getEvent().getPassId(), userData.getEvent().getCell());
            CarpTripCell nextCell = CarpTripMgr.getNextCell(userData.getEvent().getPassId(), userData.getEvent().getCell());

            if (nextCell == null) {
                return GameErrorCode.E_CARP_TRIP_REACH_TOP;
            }

            if (cell != null) {
                eCarpTripCellType cellType = eCarpTripCellType.getCellType(cell.getCellType());
                eCarpTripCellType nextCellType = eCarpTripCellType.getCellType(nextCell.getCellType());
                if (cellType == null || nextCellType == null) {
                    return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
                }
                if (!eCarpTripCellType.isConnected(cellType, userData.getEvent().getColIndex(), nextCellType, x)) {
                    return GameErrorCode.E_CARP_TRIP_NEXT_NOT_CONNECT;
                }
                if (cell.getCellNum() + 1 != nextCell.getCellNum()){
                    return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
                }
            }

            CarpTripEventResult result = new CarpTripEventResult();
            //事件处理
            CarpTripCellEvent event = nextCell.getEventList().get(x);
            eCarpTripEventType eventType = eCarpTripEventType.getType(event.getEventType());
            if (eventType == null) {
                return GameErrorCode.E_GAME_ERROR;
            }
            String beforeExp = userData.getExp().toString();
            String beforeAbility = userData.getAbility().toString();
            eLogMoneyType logType = eLogMoneyType.CarpTripActivity;
            CarpTripProto.CarpTripClimbRespMsg.Builder respMsg = CarpTripProto.CarpTripClimbRespMsg.newBuilder();
            boolean upgradeLv = false;
            boolean addCellNum = false;
            int beforeCellNum = userData.getCellNum();
            switch (eventType) {
                case Weapons:
                    if (!userData.getPreHandleList().contains(nextCell.getCellNum())) {
                        userData.setAbility(new BigInteger(event.getEventVal()).add(userData.getAbility()));
                    }
                    break;
                case Traps:
                    userData.setAbility(userData.getAbility().subtract(new BigInteger(event.getEventVal())));
                    if (userData.getAbility().compareTo(BigInteger.ZERO) < 0) {
                        userData.setAbility(BigInteger.ZERO);
                    }
                    break;
                case Treasures:
                    userData.setAbility(userData.getAbility().multiply(new BigInteger(event.getEventVal())));
                    break;
                case Division:
                    userData.setAbility(userData.getAbility().divide(new BigInteger(event.getEventVal())));
                    break;
                case Box:
                    //宝箱奖励
                    GoodsInfo goodsInfo = GoodsMgr.getGoodsById(Integer.valueOf(event.getEventVal()));
                    if (goodsInfo == null) {
                        return GameErrorCode.E_GOODS_NO_EXIST;
                    }
                    OpenGoodsBagResult openResult = GoodsBagMgr.getRandomGoods(goodsInfo.getGoodsId());
                    //全部是灵气
                    recoverUserEnergyPower();
                    BigInteger val = openResult.getReward().getCountByGoodsId(config.getAuraItemId());
                    int beforeVal = userData.getPower();
                    userData.setPower(val.intValue() + userData.getPower());
                    respMsg.setReward(PropertyHelper.parsePropertyToString(openResult.getReward()));
                    logType = eLogMoneyType.CarpTripActivityBoxEventReward;
                    if(val.compareTo(BigInteger.ZERO) > 0){
                        //体力获得
                        AutoLogMgr.add(new LogCarpTripPower(userData.getActivityId(), player.getUserId(), 4, beforeVal, userData.getPower() - beforeVal, userData.getPower()));
                    }
                    break;
                case Monster:
                    if (userData.getAbility().compareTo(new BigInteger(event.getEventVal())) < 0) {
                        return GameErrorCode.E_CARP_TRIP_BEAT_MONSTER_FAILS;
                    }
                    userData.setCellNum(1 + userData.getCellNum());
                    //需要特殊处理，先设置
                    userData.getEvent().setPassId(nextCell.getPassId());
                    userData.getEvent().setColIndex(x);
                    addCellNum = true;
                    upgradeLv = addUserExp(userData, new BigInteger(event.getEventVal()), config);
                    if (cell != null) {
                        userData.getEvent().setPassId(cell.getPassId());
                    }
                    respMsg.setExp(event.getEventVal());
                    break;
                case Boss:
                    if (userData.getAbility().compareTo(new BigInteger(event.getEventVal())) < 0) {
                        return GameErrorCode.E_CARP_TRIP_BEAT_BOSS_FAILS;
                    }
                    //boss奖励
                    CarpTripLevelInfo levelInfo = config.getCarpTripLevelInfo(userData.getEvent().getPassId());
                    if (levelInfo != null) {
                        result.setReward(levelInfo.getReward());
                        logType = eLogMoneyType.CarpTripActivityBossEventReward;
                    }
                    userData.setCellNum(1 + userData.getCellNum());
                    //需要特殊处理，先设置
                    userData.getEvent().setPassId(nextCell.getPassId());
                    userData.getEvent().setColIndex(x);
                    addCellNum = true;
                    upgradeLv = addUserExp(userData, new BigInteger(event.getEventVal()), config);
                    if (cell != null) {
                        userData.getEvent().setPassId(cell.getPassId());
                    }
                    respMsg.setExp(event.getEventVal());
                    break;
            }

            CarpTripProto.CarpTripConfigSyncMsg.Builder configSync = CarpTripProto.CarpTripConfigSyncMsg.newBuilder();
            respMsg.setUpgrade(upgradeLv);
            UserCarpTripEvent userEvent = new UserCarpTripEvent();
            userEvent.setColIndex(x);
            //特殊处理，起步或者跳关，内部层数从0开始
            if (nextCell.getPassId() != userData.getEvent().getPassId() || beforeCellNum == 0) {
                userEvent.setCell(0);
            } else {
                userEvent.setCell(1 + userData.getEvent().getCell());
            }
            userEvent.setPassId(nextCell.getPassId());
            if (!addCellNum) {
                userData.setCellNum(1 + userData.getCellNum());
            }
            userData.setEvent(userEvent);
            if (cell != null && cell.getPassId() != nextCell.getPassId()) {
                buildPassCellTempList(config, configSync, userData.getEvent().getPassId(), userData);
            }

            if (!StringUtils.isNullOrEmpty(result.getReward())) {
                respMsg.setReward(result.getReward());
                player.getModule(CurrencyModule.class).addCurrency(result.getReward(), eLogMoneyType.CarpTripActivity, logType);
            }
            respMsg.addAllPass(configSync.getPassList());
            respMsg.setRet(0);

            CarpTripRoleInfo roleInfo = config.getCarpTripRoleInfo(userData.getExp());
            respMsg.setUserData(CarpTripActivityPb.buildUserData(userData, roleInfo));

            player.sendPacket(Protocol.U_CARP_TRIP_CLIMB, respMsg);

            player.notifyListener(eGamePlayerEventType.CarpTripCellNumCrossRank.getValue(), new ValueParamArgs(userData.getCellNum(), String.valueOf(userData.getAbility())));

            player.notifyListener(eGamePlayerEventType.CarpTripNormalCellPass.getValue(), userData.getCellNum());
            if(userData.getCellNum() >= config.getTotalCellNum()){
                syncPveData();
            }

            AutoLogMgr.add(new LogCarpTripFight(CarpTripMgr.getActivityId(), player.getUserId(), beforeCellNum, event.getEventType(), event.getEventType(),
                    beforeAbility, userData.getAbility().toString(), event.getEventVal(), beforeExp, userData.getExp().toString(), result.getReward()));

            //syncPveData();
        }
        return 0;
    }

    /**
     * 加经验
     * @param userData 玩家数据
     * @param exp 经验
     */
    private boolean addUserExp(UserCarpTripData userData, BigInteger exp, CarpTripConfig config) {
        boolean upgrade = false;
        int oLv = config.getCarpTripRoleInfo(userData.getExp()).getLevel();
        String beforeExp = userData.getExp().toString();
        userData.setExp(userData.getExp().add(exp));
        int nLv = config.getCarpTripRoleInfo(userData.getExp()).getLevel();
        if(oLv < nLv){
            int num = config.getSkillUpNum();
            for (CarpTripLevelInfo levelInfo : config.getLevelInfoList()) {
                if(levelInfo.getId() < userData.getEvent().getPassId()){
                    continue;
                }
                if(num == 0){
                    break;
                }
                for (CarpTripCell towerCell : levelInfo.getCellList()) {
                    if(num == 0){
                        break;
                    }
                    if(towerCell.getCellNum() >= userData.getCellNum()){
                        if(userData.getPreHandleList().contains(towerCell.getCellNum())){
                            num--;
                            continue;
                        }
                        for (int i = 0; i < towerCell.getEventList().size(); i++) {
                            CarpTripCellEvent event = towerCell.getEventList().get(i);
                            if(towerCell.getCellNum() == userData.getCellNum() && userData.getEvent().getColIndex() == i){
                                //当前已处理过的，不再加
                                continue;
                            }
                            if(event.getEventType() == eCarpTripEventType.Weapons.getType()){
                                userData.addPreHandle(towerCell.getCellNum());
                                userData.setAbility(userData.getAbility().add(new BigInteger(event.getEventVal())));
                            }
                        }
                        num--;
                    }
                }
            }
            upgrade = true;
            player.notifyListener(eGamePlayerEventType.CarpTripCellNumCrossRank.getValue(),  new ValueParamArgs(userData.getCellNum(), String.valueOf(userData.getAbility())));

            //升级日志
            AutoLogMgr.add(new LogCarpTripUserUpgrade(CarpTripMgr.getActivityId(), player.getUserId(), userData.getCellNum(), oLv, nLv, userData.getAbility().toString(),
                    userData.getAbility().toString(), beforeExp, userData.getExp().toString()));
        }
        return upgrade;
    }

    public void addSpecialGoods(int goodsId, BigInteger value) {
        if(userData == null){
            return;
        }
        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null){
            return;
        }
        if(goodsId == config.getExpItemId()){
            //加经验
            addUserExp(userData, value, config);
        }
        if(goodsId == config.getStrengthItemId()){
            //加实力
            userData.setAbility(userData.getAbility().add(value));
            player.notifyListener(eGamePlayerEventType.CarpTripCellNumCrossRank.getValue(),  new ValueParamArgs(userData.getCellNum(), String.valueOf(userData.getAbility())));
            uploadUserAbility();
        }
        if(goodsId == config.getAuraItemId()){
            //加体力
            recoverUserEnergyPower();
            userData.setPower(userData.getPower() + value.intValue());

            //体力日志
        }
        syncUserData();
    }

    public UserCarpTripData getUserData() {
        return userData;
    }

    /**
     * 使用体力石头
     * @param num 数量
     */
    public int useStone(int num) {

        if(userData == null){
            return GameErrorCode.E_CARP_TRIP_LOCK;
        }

        recoverUserEnergyPower();

        CarpTripConfig config = CarpTripMgr.getConfig();

        String consume = config.getAddAuraItemId() + "=" + num;

        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(config.getAddAuraItemId());
        if(goodsInfo == null){
            return GameErrorCode.E_GOODS_NO_EXIST;
        }

        if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(consume), eLogMoneyType.CarpTripActivity, eLogMoneyType.CarpTripActivityStoneConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        int beforeVal = userData.getPower();
        userData.setPower(userData.getPower() + num * goodsInfo.getParamList().get(0).intValue());

        CarpTripProto.CarpTripUseStoneGoodsRespMsg.Builder respMsg = CarpTripProto.CarpTripUseStoneGoodsRespMsg.newBuilder();
        respMsg.setPower(userData.getPower());
        respMsg.setLastRecoverPowerTime(userData.getLastRecoverPowerTime());
        respMsg.setRet(0);
        player.sendPacket(Protocol.U_CARP_TRIP_USE_STONE, respMsg);

        AutoLogMgr.add(new LogCarpTripPower(userData.getActivityId(), player.getUserId(), 3, beforeVal, userData.getPower() - beforeVal, userData.getPower()));

        return 0;
    }

    /**
     * pvp
     */
    public int fight(int cellId, long targetId) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        if(userData.getCellNum() < config.getTotalCellNum()){
            return 0;
        }

        if(cellId <= 0 || cellId > config.getPvpTopList().size()){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        CarpTripProto.CrossCarpTripPVPFightReqMsg.Builder crossReq = CarpTripProto.CrossCarpTripPVPFightReqMsg.newBuilder();
        crossReq.setActivityId(CarpTripMgr.getActivityId());
        crossReq.setCellId(cellId);
        crossReq.setTargetId(targetId);
        crossReq.setMyAbility(userData.getAbility().toString());
        UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId());
        crossReq.setBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));

        player.sendPacket(Protocol.C_CARP_TRIP_PVP_FIGHT, crossReq);
        return 0;
    }

    /**
     * 弹珠机
     */
    public int draw(int type) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        int times = 1;

        //弹珠机
        CarpTripDrawUpInfo drawUpInfo = config.getCarpTripDrawUpInfo(userData.getDrawUpLv());
        if(drawUpInfo == null){
            return GameErrorCode.E_GAME_ERROR;
        }

        recoverUserEnergyPower();

        //自动换一个体力
        int needPower = 0;

        //没有次数
        if(userData.getLaunchTimes() <= 0){
            needPower = drawUpInfo.getCost();
            //没有体力
            if(userData.getPower() <= 0 || userData.getPower() < needPower){
                return GameErrorCode.E_CARP_TRIP_POWER_NO_ENOUGH;
            }
            userData.setLaunchTimes(userData.getLaunchTimes() + drawUpInfo.getShootNum());
        }

        //一键使用
        if(type == 1) {
            times = userData.getLaunchTimes();
        }

        List<CarpTripEventInfo> list = config.getEventInfoByType(1);
        if(list.size() != 7 || config.getDrawWeightList().size() != 7){
            return GameErrorCode.E_GAME_ERROR;
        }

        Random random = new Random();

        CarpTripProto.CarpTripDrawRespMsg.Builder respMsg = CarpTripProto.CarpTripDrawRespMsg.newBuilder();

        //总奖励
        Property reward = new Property();
        //上公告的档位
        //List<Integer> lotteryList = new ArrayList<>();
        //List<ActivityConditionInfo> conditionInfoList = NormalActivityMgr.getActivityConditionInfoListByType(userData.getActivityId(), eGamePlayerEventType.CarpTripBigDrawProcess.getValue());
        //for (ActivityConditionInfo conditionInfo : conditionInfoList) {
            //if(conditionInfo.getParamList().get(0).compareTo(BigInteger.ONE) == 0){
            //    lotteryList.add(conditionInfo.getParamList().get(3).intValue());
            //}
        //}

        String beforeAbility = userData.getAbility().toString();
        String beforeExp = userData.getExp().toString();

        List<Integer> listDropPositionList = new ArrayList<>();
        //大奖进度
        int tempProcess = userData.getDrawProcess();
        Map<Integer, String> tempDrawMap = new HashMap<>(userData.getDrawRewardMap());
        //所奖励，按配置而非入背包的道具
        Property allRoundReward = new Property();
        int bigRewardTimes = 0;
        //次数
        for (int i = 0; i < times; i++) {
            int idx = RandomHelper.getRandomIndexByWeight(config.getDrawWeightList(), random);
            boolean bigReward = false;
            if(idx != 3){
                if(random.nextInt(1000) < config.getDRAW_ISBIG()){
                    //大奖
                    bigReward = true;
                    bigRewardTimes++;
                    tempProcess += config.getDRAW_BIG_PRO();
                }
            }
            //当次奖励
            Property roundReward = new Property();
            CarpTripProto.CarpTripDrawTimesRewardTemp.Builder roundRewardBuilder = CarpTripProto.CarpTripDrawTimesRewardTemp.newBuilder();
            calSingleDrawResultReward(config, reward, roundReward, roundRewardBuilder, new CarpTripDrawResult(idx, bigReward));
            respMsg.addReward(roundRewardBuilder);

            //统计获得的道具数量
            for (Map.Entry<Integer, BigInteger> entry : roundReward.getGoods().entrySet()) {
                allRoundReward.addProperty(entry.getKey(), BigInteger.ONE);
            }

            //是否上公告
            //if(lotteryList.contains(tempProcess) && !tempDrawMap.containsKey(tempProcess)){
            //    tempDrawMap.put(tempProcess, PropertyHelper.parsePropertyToString(roundReward));
            //}
            listDropPositionList.add(idx);
        }

        int beforePower = userData.getPower();
        userData.setPower(userData.getPower() - needPower);

        //消耗体力才有积分
        if(needPower > 0){
            reward.addProperty(config.getScoreItemId(), BigInteger.valueOf(config.getDrawScoreBase() * needPower));
        }
        //奖励计算
        getRewardAndCompleteTask(userData, reward, config, allRoundReward);

        //重新计算弹珠机等级
        int lv = CarpTripMgr.getDrawUpLv(userData.getDrawExp(), config);
        userData.setDrawUpLv(lv);

        userData.setDrawTimes(times + userData.getDrawTimes());
        userData.setDrawProcess(tempProcess);
        userData.setLaunchTimes(userData.getLaunchTimes() - times);
        userData.setDrawRewardMap(tempDrawMap);

        //大奖进度成就
        player.notifyListener(eGamePlayerEventType.CarpTripBigDrawProcess.getValue(), userData.getDrawProcess());

        player.notifyListener(eGamePlayerEventType.CarpTripCellNumCrossRank.getValue(),  new ValueParamArgs(userData.getCellNum(), String.valueOf(userData.getAbility())));

        CarpTripRoleInfo roleInfo = config.getCarpTripRoleInfo(userData.getExp());
        respMsg.setRet(0);
        respMsg.setUserData(CarpTripActivityPb.buildUserData(userData, roleInfo));

        player.sendPacket(Protocol.U_CARP_TRIP_DRAW, respMsg);

        if(needPower > 0){
            //灵气日志
            AutoLogMgr.add(new LogCarpTripPower(userData.getActivityId(), player.getUserId(), 0, beforePower, needPower, userData.getPower()));
        }

        if(reward.getCountByGoodsId(config.getStrengthItemId()).compareTo(BigInteger.ZERO) > 0){
            syncPveData();
        }

        AutoLogMgr.add(new LogCarpTripDraw(userData.getActivityId(), player.getUserId(), times, needPower, PropertyHelper.parsePropertyToString(reward),
                beforePower, userData.getPower(), beforeAbility, userData.getAbility().toString(), beforeExp, userData.getExp().toString(), needPower * config.getDrawScoreBase(),
                StringUtils.listToString(listDropPositionList, ","), userData.getDrawUpLv(), bigRewardTimes));


        return 0;
    }

    private void getRewardAndCompleteTask(UserCarpTripData userData, Property reward, CarpTripConfig config, Property allRoundReward) {

        //实力
        BigInteger ability = reward.getCountByGoodsId(config.getStrengthItemId());
        if(ability.compareTo(BigInteger.ZERO) > 0){
            userData.setAbility(userData.getAbility().add(ability));
            //uploadUserAbility();
        }
        //经验
        BigInteger exp = reward.getCountByGoodsId(config.getExpItemId());
        if(exp.compareTo(BigInteger.ZERO) > 0){
            //userData.setExp(userData.getExp().add(exp));
            addUserExp(userData, exp, config);
        }

        //鱼籽
        BigInteger yuZi = reward.getCountByGoodsId(config.getYuZiItemId());
        if(yuZi.compareTo(BigInteger.ZERO) > 0){
            userData.setDrawExp(yuZi.intValue() + userData.getDrawExp());
        }

        //积分
        BigInteger score = reward.getCountByGoodsId(config.getScoreItemId());
        if(score.compareTo(BigInteger.ZERO) > 0){
            Property bagReward = new Property(config.getScoreItemId(), score);
            userData.setScore(userData.getScore() + score.intValue());
            player.getModule(CurrencyModule.class).addCurrency(bagReward, eLogMoneyType.CarpTripActivity, eLogMoneyType.CarpTripActivityDrawReward);
        }

        for (Map.Entry<Integer, BigInteger> entry : allRoundReward.getGoods().entrySet()) {
            userData.addDrawCount(entry.getKey(), entry.getValue().intValue());
        }
    }

    /**
     * 奖励计算
     * @param config 配置
     * @param reward 所有奖励
     * @param roundReward 当前奖励（给客户端）
     * @param roundRewardBuilder 当前奖励（给客户端）
     * @param drawResult 弹珠结果
     */
    private void calSingleDrawResultReward(CarpTripConfig config, Property reward, Property roundReward, CarpTripProto.CarpTripDrawTimesRewardTemp.Builder roundRewardBuilder, CarpTripDrawResult drawResult) {
        CarpTripProto.CarpTripDrawRewardTemp.Builder rewardBuild = CarpTripProto.CarpTripDrawRewardTemp.newBuilder();
        rewardBuild.setAbility("0");
        rewardBuild.setExp("0");
        rewardBuild.setPower(0);
        rewardBuild.setScore(0);
        rewardBuild.setYuZi(0);
        rewardBuild.setStar(drawResult.isBig());
        rewardBuild.setSeven(drawResult.getPosition());
        CarpTripRoleInfo roleInfo = config.getCarpTripRoleInfo(userData.getExp());
        if(roleInfo == null){
            return;
        }

        List<CarpTripEventInfo> list = config.getEventInfoByType(1);

        CarpTripEventInfo eventInfo = list.get(drawResult.getPosition());
        if(eventInfo.getLittleType() == 1){
            //战力
            BigInteger val = new BigDecimal(roleInfo.getAddEffect()).multiply(new BigDecimal(eventInfo.getExParam())).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).toBigInteger();
            reward.addProperty(config.getStrengthItemId(), val);
            roundReward.addProperty(eventInfo.getItemId(), val);
            rewardBuild.setAbility(val.toString());
        }else if(eventInfo.getLittleType() == 3){
            //鱼籽写死  1000
            BigInteger val = new BigInteger(eventInfo.getExParam());
            reward.addProperty(config.getYuZiItemId(), val);
            roundReward.addProperty(eventInfo.getItemId(), val);
            rewardBuild.setYuZi(val.intValue());
        }else if(eventInfo.getLittleType() == 2){
            //经验
            BigInteger val = new BigDecimal(roleInfo.getAddEffect()).multiply(new BigDecimal(eventInfo.getExParam())).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).toBigInteger();
            reward.addProperty(config.getExpItemId(), val);
            roundReward.addProperty(eventInfo.getItemId(), val);
            rewardBuild.setExp(val.toString());
        }

        //积分
        //roundReward.addProperty(config.getScoreItemId(), BigInteger.valueOf(config.getDrawScoreBase()));
        //rewardBuild.setScore(config.getDrawScoreBase());
        //总奖励
        //reward.addProperty(config.getScoreItemId(), BigInteger.valueOf(config.getDrawScoreBase()));


        rewardBuild.setReward(PropertyHelper.parsePropertyToString(roundReward));
        roundRewardBuilder.setReward(rewardBuild);
    }

    /**
     * 上报玩家实力
     */
    public void uploadUserAbility(){
        if(userData.getCellNum() >= CarpTripMgr.getConfig().getTotalCellNum() && userData.getTopCellNum() > 0){
            CarpTripProto.CarpTripPVPAbilityUploadMsg.Builder builder = CarpTripProto.CarpTripPVPAbilityUploadMsg.newBuilder();
            builder.setActivityId(CarpTripMgr.getActivityId());
            builder.setUserId(player.getUserId());
            builder.setAbility(userData.getAbility().toString());
            player.sendPacket(Protocol.C_CARP_TRIP_UPLOAD_ABILITY, builder);
        }
    }

    /**
     * 战斗结果
     */
    public int fightResult(CarpTripProto.CarpTripPVPFightRespMsg respMsg) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        CarpTripProto.CarpTripPVPFightRespMsg.Builder clientMsg = respMsg.toBuilder();
        String reward = "";
        if(userData != null){
            userData.setTopCellNum(respMsg.getNewCellId());
            boolean hasReward = false;
            if(!userData.getTopCellList().contains(respMsg.getNewCellId())){
                hasReward = true;
                userData.getTopCellList().add(respMsg.getNewCellId());
            }
            if(hasReward){
                CarpTripPvpTopInfo tripPvpTopInfo = config.getCarpTripPvpTopInfo(respMsg.getNewCellId());
                if(tripPvpTopInfo != null){
                    clientMsg.setReward(tripPvpTopInfo.getReward());
                    player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parseStringToProperty(tripPvpTopInfo.getReward()), eLogMoneyType.CarpTripActivity, eLogMoneyType.CarpTripActivityPVPReward);
                    reward = tripPvpTopInfo.getReward();
                }
            }
        }

        player.sendPacket(Protocol.U_CARP_TRIP_PVP_FIGHT, clientMsg);

        //日志
        AutoLogMgr.add(new LogCarpTripTopFight(userData.getActivityId(), userData.getUserId(), userData.getAbility().toString(), respMsg.getNewCellId(),
                respMsg.getEnemyUserId(), respMsg.getEnemyAbility(), reward));
        return 0;
    }

    public int readReport() {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        userData.setLastReadTime(System.currentTimeMillis());
        return 0;
    }

    public void addReport(CarpTripPvPReportData data) {
        reportDataList.add(data);
        userData.setTopCellNum(data.getNewCellNum());
        CarpTripMgr.getLogger().info("-------跃龙门----- player {} drop to {}", player.getUserId(), userData.getTopCellNum());

        player.sendPacket(Protocol.U_CARP_TRIP_PVP_REPORT_NOTIFY, CarpTripActivityPb.buildReportBuilder(data));
    }

    public int getReportList() {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        CarpTripProto.CarpTripPVPReportListRespMsg.Builder respMsg = CarpTripProto.CarpTripPVPReportListRespMsg.newBuilder().setRet(0);
        for (int i = 0; i < reportDataList.size(); i++) {
            CarpTripPvPReportData reportData = reportDataList.get(i);
            respMsg.addReport(CarpTripActivityPb.buildReportBuilder(reportData));
        }
        if(reportDataList.size() > 0){
            CarpTripPvPReportData reportData = reportDataList.get(reportDataList.size() - 1);
            if(reportData.getTime() > userData.getLastReadTime()){
                respMsg.addReport(CarpTripActivityPb.buildReportBuilder(reportData));
            }
        }
        player.sendPacket(Protocol.U_CARP_TRIP_PVP_REPORT_LIST, respMsg);
        return 0;
    }

    /**
     * 暂存合成游戏
     */
    public int dragonUpSave(String data) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        userData.setGameData(data);
        player.sendPacket(Protocol.U_CARP_TRIP_DRAGON_UP_SAVE, CarpTripProto.CarpTripDragonUpSaveRespMsg.newBuilder().setRet(0));
        return 0;
    }

    /**
     * 合成游戏奖励
     */
    public int getDragonUpReward(int id, boolean win) {
        if(userData == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        if(userData.getDragonIdList().containsKey(id)){
            return GameErrorCode.E_ACTIVITY_REWARD_IS_GET;
        }
        CarpTripConfig config = CarpTripMgr.getConfig();
        if(config == null) {
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }
        CarpTripDragonUpInfo dragonUpInfo = config.getCarpTripDragonUpInfo(id);
        if(dragonUpInfo == null){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        userData.getDragonIdList().put(id, win);
        String reward = "";
        CarpTripProto.CarpTripDragonUpGetRewardRespMsg.Builder respMsg = CarpTripProto.CarpTripDragonUpGetRewardRespMsg.newBuilder();
        if(win){
            player.getModule(CurrencyModule.class).addCurrency(dragonUpInfo.getReward(), eLogMoneyType.CarpTripActivity, eLogMoneyType.CarpTripActivityDragonUp);
            respMsg.setReward(dragonUpInfo.getReward());
            reward = dragonUpInfo.getReward();
        }
        respMsg.setRet(0);
        player.sendPacket(Protocol.U_CARP_TRIP_DRAGON_UP_REWARD, respMsg);
        syncUserData();

        AutoLogMgr.add(new LogCarpTripDragonUpResult(userData.getActivityId(), player.getUserId(), id, reward, win ? 1 : 2));
        return 0;
    }

    public void getBigDrawProcess(int param4, String reward) {
        if(userData == null){
            return;
        }
        try{
            int index = 0;
            List<ActivityConditionInfo> conditionInfoList = NormalActivityMgr.getActivityConditionInfoListByType(userData.getActivityId(), eGamePlayerEventType.CarpTripBigDrawProcess.getValue());
            for (ActivityConditionInfo conditionInfo : conditionInfoList) {
                if(param4 >= conditionInfo.getParamList().get(3).intValue()){
                    index++;
                }
                if(conditionInfo.getParamList().get(3).intValue() == param4){
                    break;
                }
            }
            if(index > 0) {
                CarpTripProto.CarpTripUploadDrawNoticeMsg.Builder uploadMsg = CarpTripProto.CarpTripUploadDrawNoticeMsg.newBuilder();
                uploadMsg.setActivityId(userData.getActivityId());
                CarpTripProto.CarpTripNoticeMsg.Builder notice = CarpTripProto.CarpTripNoticeMsg.newBuilder();
                notice.setReward(reward);
                notice.setValue(index);
                notice.setServerId(GameServer.getInstance().getServerId());
                notice.setNickName(player.getUserInfo().getNickName());
                notice.setTime(System.currentTimeMillis());
                uploadMsg.addNotice(notice);
                //跨服公告
                if (uploadMsg.getNoticeCount() > 0) {
                    player.sendPacket(Protocol.C_CARP_TRIP_UPLOAD_DRAW_NOTICE, uploadMsg);
                }
            }else {

            }
        }catch (Exception e){
            CarpTripMgr.getLogger().info("玩家{} 领取大奖档位，上报公告出错", player.getUserId());
            CarpTripMgr.getLogger().error(e);
        }
    }

    public int clientSave(int data) {
        CarpTripProto.CarpTripClientSaveRespMsg.Builder respMsg = CarpTripProto.CarpTripClientSaveRespMsg.newBuilder();
        respMsg.setRet(0);
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        userData.setClientSave(data);
        respMsg.setData(data);
        player.sendPacket(Protocol.U_CARP_TRIP_CLIENT_SAVE, respMsg);

        syncUserData();
        return 0;
    }
}
